



import bpy
from bpy.types import Operator
import bmesh
import numpy as np

#from 全局控制.Node.节点数据类型 import bl_集合数据类型
#from 全局控制.Node.节点和插座基类.bl_UpdateNode import *
import 全局控制.Node.节点和插座基类.bl_节点基类 as 基类
import 全局控制.Node.插座.bl_插座基类 as 插件基类
import 物体.物体管理.物体数据 as 物体数据
import Core.bl_物体添加删除 as 物体添加删除
import Core.bl_单元查找 as 单元查找







class C_SN_体素遮罩(基类.C_SN_基类):
	bl_dname = 'bl_node_体素遮罩'
	bl_label = '体素遮罩'
	
	
	def init(self, context):
		super(C_SN_体素遮罩, self).f_init(context)
		self.inputs.new('C_NodeSocket_物体', name='包裹物体')
		self.inputs.new('C_NodeSocket_bool', name='初始化数据')
		self.inputs.new('C_NodeSocket_3i', name='维度')
		self.inputs.new('C_NodeSocket_3f', name='间距')
		self.inputs.new('C_NodeSocket_3f', name='偏移')
		self.inputs.new('C_NodeSocket_3f', name='Lower')
		self.inputs.new('C_NodeSocket_3f', name='Upper')
		self.inputs.new('C_NS_List_T', name='MASK索引正')
		self.inputs.new('C_NS_List_T', name='MASK索引负')
		
		self.outputs.new('C_NS_List_T', name='MASK')

		self.inputs['MASK索引'].f_set维度(0, 默认值=-1)
		self.inputs['MASK'].f_set维度(0, T='B', 默认值=True)


	def f_init遮罩数据(self, value):
		pass

	def f_init单元数据(self):
		初始化数据 = self.inputs['初始化数据'].f_getData()
		维度 = self.inputs['维度'].f_getData()
		#print('--- 初始化数据 ---', 初始化数据)
		data = [初始化数据] * (维度[0]*维度[1]*维度[2])
		self.outputs['MASK'].f_setData(data)

	def f_set遮罩单元(self, 正负, input插座, 上层Output):
		socket = self.outputs['MASK']
		if 上层Output :
			data = 上层Output.f_getData()
		else:
			data = input插座.f_getData()

		for i in data:
			socket.f_setKeyData(正负, i)
			

	def f_input插座Update(self, input插座, 上层Output=None):
		#print('input插座 = ', self, input插座.name, 上层Output)
		if input插座.name == '初始化数据':
			self.f_init单元数据()
		elif input插座.name == '维度':
			self.f_init单元数据()

		elif input插座.name == 'MASK索引正':
			self.f_set遮罩单元(True, input插座, 上层Output)
		elif input插座.name == 'MASK索引负':
			self.f_set遮罩单元(False, input插座, 上层Output)

	
	def f_update(self, 是否向下传递=False, input插座=None):
		维度 = self.inputs['维度'].f_getData()
		num = 维度[0]*维度[1]*维度[2]
		if len(self.outputs['MASK'].f_getData()) != num :
			self.f_init单元数据()


		间距 = self.inputs['间距'].f_getData()
		偏移 = self.inputs['偏移'].f_getData()
		Lower = self.inputs['Lower'].f_getData()
		Upper = self.inputs['Upper'].f_getData()

		偏移[0] -= 间距[0]*0.5
		偏移[1] += 间距[1]*0.5
		偏移[2] -= 间距[2]*0.5


		newMask = []
		socket = self.outputs['MASK']
		objs = self.inputs['包裹物体'].f_getData()
		if len(objs) :
			包围盒 = tuple(Lower+Upper)
			体素 = 物体数据.f_get物体体素(objs, bpy.context, 包围盒, 间距=tuple(间距))
			#self.outputs['MASK'].f_setData(体素)
			
			体素 = np.array(体素)
			体素 = 体素.reshape((维度[2], 维度[1], 维度[0]))
			bm = bmesh.new()
			for z in range(维度[2]):
				#print('z = ', z)
				for y in range(维度[1]):
					#print('y = ', y)
					for x in range(维度[0]):
						#print('x = ', x)
						坐标 = [x, z, y]
						line索引 = 单元查找.f_坐标转索引(维度, 坐标)
						#print('体素[z, y, x] = ', 体素[z, y, x])
						if 体素[z, y, x] > 0:
							v = (间距[0]*x+偏移[0], 间距[1]*z+偏移[1], 间距[2]*y+偏移[2])
							bmesh.ops.create_vert(bm, co=v)
							#print('体素[z, y, x] = ', v)
							socket.f_setKeyData(1, line索引)
						else:
							socket.f_setKeyData(0, line索引)
			
			
			meID = bpy.data.meshes.find('Mesh_域体素可视')
			if meID >= 0 :
				me = bpy.data.meshes[meID]
			else:
				me = bpy.data.meshes.new("Mesh_域体素可视")
			bm.to_mesh(me)
			bm.free()
			
			#print('顶点 = ',  顶点, 索引)
			#me.from_pydata(vertices=顶点, edges=[(0,1)], faces=索引)
			
			meID = bpy.data.objects.find('Mesh_域体素可视')
			if meID >= 0 :
				obj = bpy.data.objects[meID]
			else:
				obj = bpy.data.objects.new(name='Mesh_域体素可视', object_data=me)
				obj.data = me


			物体添加删除.f_添加物体到集合('__域体素可视__', obj)
			
		super(C_SN_体素遮罩, self).f_update(是否向下传递, input插座)
		
		





class C_NODE_AddMenu_体素遮罩(bpy.types.Operator):
	bl_idname = 'node.global_node_voxelmask_add'
	bl_label = '体素遮罩'
	bl_options = {'REGISTER', 'UNDO'}
	
	def execute(operator, context):
		bpy.ops.node.add_node(type='C_SN_体素遮罩', use_transform=True)
		return {'FINISHED'}



classes = (
	C_SN_体素遮罩,
	C_NODE_AddMenu_体素遮罩,
	
)

def register():
	for c in classes:
		bpy.utils.register_class(c)
		

def unregister():
	for c in classes:
		bpy.utils.unregister_class(c)

	





